package com.xgf.util;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.aspectj.util.FileUtil;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

/**
 * FTP工具类
 *
 * @author <a href="zhaoxiangyu@tulong.com">zhaoxiangyu</a>
 * @date 2017/8/15 10:50
 */
public class FtpUtil {
    private String ip;//上传地址
    private String username;
    private String password;
    private String addr;//下载地址，要求带http或https
    private String tempDir;//临时文件夹
    private String screenToolPath;//视频截图工具路径

    /**
     * 上传文件到FTP服务器
     *
     * @param uploadFile
     * @param savePath
     * @return
     * @throws Exception
     */
    public FtpFile saveFileToFTPServer(File uploadFile, String savePath) throws Exception {
        FtpFile ftpFile=new FtpFile();
        String suffix=uploadFile.getName().substring(uploadFile.getName().lastIndexOf(".")+1);
        String fileName=getRandomName()+"."+suffix;
        ftpFile.setName(fileName);
        ftpFile.setSize(uploadFile.length());
        ftpFile.setUrl(upload(uploadFile,fileName,savePath));

        return ftpFile;
    }

    /**
     * 保存base64文件到FTP服务器
     *
     * @param base64Str
     * @param savePath
     * @return
     * @throws Exception
     */
    public FtpImageFile saveBase64FileToFTPServer(String base64Str,String savePath) throws Exception {
        if(!Base64Util.isImageFromBase64(base64Str)){
            throw  new Exception("上传的不是图片文件");
        }
        String fileName=getRandomName()+".jpg";

        String tempPath=tempDir+"/"+fileName;
        if(!Base64Util.generateImage(base64Str,tempPath)){
            throw new Exception("base64转文件失败");
        }

        File file=new File(tempPath);
        BufferedImage bufferedImage = ImageIO.read(file);

        FtpImageFile imageFile=new FtpImageFile();
        imageFile.setName(fileName);
        imageFile.setWidth(bufferedImage.getWidth());
        imageFile.setHeight(bufferedImage.getHeight());
        imageFile.setSize(file.length());
        imageFile.setUrl(upload(file,fileName,savePath));

        file.delete();
        return imageFile;
    }

    /**
     * 上传视频到FTP服务器(生成截图)
     *
     * @param file
     * @param savePath
     * @return
     * @throws Exception
     */
    public FtpVideoFile saveVideoFileToFTPServer(CommonsMultipartFile file,String savePath) throws Exception {
        //获取客户端传来的文件类型
        String fileType = file.getContentType().substring(0,file.getContentType().indexOf("/"));
        //因为是视频接口，所以不是video类型则报错（只能为image或video）
        if(!fileType.equals("video") || StringUtils.isEmpty(fileType)) {
            throw new Exception("文件不是视频:"+fileType);
        }
        if(file.isEmpty()||file.getSize()==0){
            throw new Exception("文件是空的");
        }

        String suffix = file.getContentType().substring(file.getContentType().lastIndexOf("/") + 1);
        String videoName=getRandomName()+"."+suffix;
        String tempVideoPath=tempDir+"/"+videoName;
        File tempVideoFile=new File(tempVideoPath);
        file.transferTo(tempVideoFile);

        String screenImageName=getRandomName()+".jpg";
        String tempScreePath=tempDir+"/"+screenImageName;
        File tempScreeFile=new File(tempScreePath);
        BufferedImage bufferedImage = ImageIO.read(tempScreeFile);
        FtpImageFile imageFile=new FtpImageFile();
        imageFile.setName(screenImageName);
        imageFile.setWidth(bufferedImage.getWidth());
        imageFile.setHeight(bufferedImage.getHeight());
        imageFile.setSize(tempScreeFile.length());
        imageFile.setUrl(upload(tempScreeFile,screenImageName,savePath+"/screeImage"));

        FtpVideoFile ftpVideoFile=new FtpVideoFile();
        ftpVideoFile.setName(videoName);
        ftpVideoFile.setSize(file.getSize());
        ftpVideoFile.setUrl(upload(tempVideoFile,videoName,savePath));
        ftpVideoFile.setScreenImage(imageFile);

        //删除临时文件
        tempScreeFile.delete();
        tempVideoFile.delete();

        return  ftpVideoFile;
    }

    /**
     * 上传文件到ftp服务器
     *
     * @param uploadFile
     * @param fileName
     * @param savePath
     * @return
     * @throws Exception
     */
    private String upload(File uploadFile,String fileName,String savePath) throws Exception {
        if(uploadFile==null){
            throw new Exception("uploadFile is null");
        }
        if(StringUtils.isEmpty(fileName)){
            throw new Exception("fileName is empty");
        }
        if(StringUtils.isEmpty(savePath)){
            throw new Exception("savePath is empty");
        }
        FTPClient ftpClient = new FTPClient();
        FileInputStream fis = null;

        try {
            //连接ftp server
            ftpClient.connect(getIp());
            if(!ftpClient.login(getUsername(),getPassword())){
                throw new Exception("登录失败:{ip="+getIp()+",username="+getUsername()+",password="+getPassword()+"}");
            }
            //设置上传文件
            fis = new FileInputStream(uploadFile);
            // 设置ftp文件存储目录
            savePath = savePath.replace("\\", "/");
            if (savePath.indexOf("/") < 0) {
                savePath = "/" + savePath;
            }
            String dirs[] = savePath.split("/");
            String d = "";
            for (String dir : dirs) {
                if (!dir.equals("")) {
                    d = d + dir + "/";
                    ftpClient.makeDirectory(d);
                }
            }
            ftpClient.changeWorkingDirectory(savePath);
            ftpClient.setBufferSize(1024);
            ftpClient.setControlEncoding("UTF-8");
            // 设置文件类型（二进制）
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.storeFile(fileName, fis);

        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("FTP客户端出错",e);
        }finally {
            IOUtils.closeQuietly(fis);
            try {
                ftpClient.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("关闭FTP连接发生异常！", e);
            }
        }

        if(!savePath.startsWith("/")){
            savePath="/"+savePath;
        }
        if(!savePath.endsWith("/")){
            savePath+="/";
        }

        return getAddr()+savePath+fileName;
    }

    /**
     * 删除FTP服务器上的文件
     *
     * @param fileUrl
     * @return
     * @throws Exception
     */
    public boolean deleteFileFromFTPServer(String fileUrl) throws Exception {
        if(StringUtils.isEmpty(fileUrl)){
            throw new Exception("fileUrl is empty");
        }
        FTPClient ftpClient = new FTPClient();
        boolean ret = false;
        try {
            //连接ftp server
            ftpClient.connect(getIp());
            if(!ftpClient.login(getUsername(),getPassword())){
                throw new Exception("登录失败:{ip="+getIp()+",username="+getUsername()+",password="+getPassword()+"}");
            }
            String regex = getAddr();
            String paths[] = fileUrl.split(regex);
            String delePath = "";
            for (String path : paths) {
                if (!path.equals("")) {
                    delePath = path;
                }
            }
            if(delePath.startsWith("/")){
                delePath=delePath.substring(1);
            }
            if(StringUtils.isEmpty(delePath)||!delePath.contains(".")){
                throw new Exception("无效的请求路径;"+fileUrl);
            }
            ret = ftpClient.deleteFile(delePath);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("FTP客户端出错",e);
        }finally {
            try {
                ftpClient.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("关闭FTP连接发生异常！", e);
            }
        }
        return ret;
    }

    private String getRandomName(){
       return UUID.randomUUID().toString().replace("-","");
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public String getTempDir() {
        return tempDir;
    }

    public void setTempDir(String tempDir) {
        this.tempDir = handleTempDir(tempDir);
    }

    public String getScreenToolPath() {
        return screenToolPath;
    }

    public void setScreenToolPath(String screenToolPath) {
        this.screenToolPath = handleScreenToolPath(screenToolPath);
    }

    private String handleTempDir(String tempDir){
        try {
           tempDir=appendProjectPath(tempDir);
            File file=new File(tempDir);
            if(!file.exists()){
                file.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tempDir;
    }

    private String handleScreenToolPath(String screenToolPath){
        if(SystemUtil.isWindow()){
            screenToolPath= appendProjectPath(screenToolPath);
        }
        return screenToolPath;
    }

    private String appendProjectPath(String path){
        if(path.startsWith("/")){
            path=getProjectPath()+path;
        }else{
            path=getProjectPath()+"/"+path;
        }
        return path;
    }

    private String getProjectPath(){
        String path=this.getClass().getClassLoader().getResource("").getPath();
        if(SystemUtil.isWindow()){
            if(path.startsWith("/")){
                path=path.substring(1);
            }
        }
        return path.substring(0,path.lastIndexOf("/WEB-INF/classes/"));
    }

    private static String txt2String(String filePath){
        File file=new File(filePath);
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while((s = br.readLine())!=null){//使用readLine方法，一次读一行
                result.append(System.lineSeparator()+s);
            }
            br.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        return result.toString();
    }
}
